/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { COMMAND_PRIORITY_LOW, PASTE_COMMAND } from 'lexical';
import { useEffect } from 'react';

/**
 * 转换font标签的size属性为像素值
 * @param size font标签的size属性值
 * @returns 转换后的像素值字符串
 */
function convertFontSizeToPixels(size: string | number): string {
  // 如果是数字字符串或数字，按照HTML font标签的size属性规则转换
  const numSize = typeof size === 'string' ? parseInt(size, 10) : size;
  
  if (isNaN(numSize)) {
    return '15px'; // 默认字体大小
  }

  // HTML font标签的size属性映射到像素值
  const sizeMap: { [key: number]: string } = {
    1: '10px',
    2: '13px',
    3: '15px', // 默认大小
    4: '18px',
    5: '24px',
    6: '32px',
    7: '48px',
  };

  return sizeMap[numSize] || '15px';
}

/**
 * 从font标签的style属性中提取font-size
 * @param style CSS样式字符串
 * @returns 提取的字体大小或null
 */
function extractFontSizeFromStyle(style: string): string | null {
  const match = style.match(/font-size:\s*([^;]+)/i);
  if (match) {
    const fontSize = match[1].trim();
    // 如果是pt单位，转换为px
    if (fontSize.endsWith('pt')) {
      const ptValue = parseFloat(fontSize);
      const pxValue = Math.round((ptValue * 4) / 3); // 1pt = 4/3px
      return `${pxValue}px`;
    }
    return fontSize;
  }
  return null;
}

/**
 * 收集元素祖先font标签的累积样式
 * @param element 要检查的元素
 * @returns 累积的样式对象
 */
function getInheritedFontStyles(element: Element): {
  fontSize?: string;
  color?: string;
  [key: string]: string | undefined;
} {
  const inheritedStyles: {
    fontSize?: string;
    color?: string;
    [key: string]: string | undefined;
  } = {};
  
  let currentElement = element.parentElement;
  
  while (currentElement) {
    if (currentElement.tagName.toLowerCase() === 'font') {
      // 从外层到内层，外层样式优先级更低，只在没有设置时才使用
      
      // 处理color属性
      const color = currentElement.getAttribute('color');
      if (color && !inheritedStyles.color) {
        inheritedStyles.color = color;
      }
      
      // 处理size属性
      const size = currentElement.getAttribute('size');
      if (size && !inheritedStyles.fontSize) {
        const fontSize = convertFontSizeToPixels(size);
        inheritedStyles.fontSize = fontSize;
      }
      
      // 处理style属性
      const styleAttr = currentElement.getAttribute('style');
      if (styleAttr) {
        // 提取font-size（优先级高于size属性）
        const fontSizeFromStyle = extractFontSizeFromStyle(styleAttr);
        if (fontSizeFromStyle && !inheritedStyles.fontSize) {
          inheritedStyles.fontSize = fontSizeFromStyle;
        }
        
        // 提取其他样式
        const otherStyles = styleAttr.replace(/font-size:\s*[^;]+;?/gi, '');
        if (otherStyles) {
          // 解析其他样式属性
          const styleDeclarations = otherStyles.split(';');
          for (const decl of styleDeclarations) {
            const [property, value] = decl.split(':').map(s => s.trim());
            if (property && value && !inheritedStyles[property]) {
              inheritedStyles[property] = value;
            }
          }
        }
      }
    }
    currentElement = currentElement.parentElement;
  }
  
  return inheritedStyles;
}

/**
 * 转换font标签为现代HTML结构
 * @param htmlString 包含font标签的HTML字符串
 * @returns 转换后的HTML字符串
 */
function transformFontTags(htmlString: string): string {
  // 使用临时DOM来解析和转换HTML
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = htmlString;

  // 递归处理所有font标签，从外层到内层
  function processFontTags(element: Element) {
    // 找到所有直接子节点中的font标签
    const childFontTags = Array.from(element.children).filter(
      child => child.tagName.toLowerCase() === 'font'
    );
    
    for (const fontTag of childFontTags) {
      // 先递归处理子节点中的font标签
      processFontTags(fontTag);
      
      // 然后处理当前font标签
      const span = document.createElement('span');
      
      // 获取继承的样式
      const inheritedStyles = getInheritedFontStyles(fontTag);
      
      // 收集当前标签的样式
      const currentStyles: { [key: string]: string } = {};
      
      // 处理color属性
      const color = fontTag.getAttribute('color');
      if (color) {
        currentStyles.color = color;
      }
      
      // 处理size属性
      const size = fontTag.getAttribute('size');
      if (size) {
        const fontSize = convertFontSizeToPixels(size);
        currentStyles['font-size'] = fontSize;
      }
      
      // 处理style属性
      const styleAttr = fontTag.getAttribute('style');
      if (styleAttr) {
        // 提取font-size（优先级高于size属性）
        const fontSizeFromStyle = extractFontSizeFromStyle(styleAttr);
        if (fontSizeFromStyle) {
          currentStyles['font-size'] = fontSizeFromStyle;
        }
        
        // 添加其他样式
        const otherStyles = styleAttr.replace(/font-size:\s*[^;]+;?/gi, '').trim();
        if (otherStyles) {
          const styleDeclarations = otherStyles.split(';');
          for (const decl of styleDeclarations) {
            const [property, value] = decl.split(':').map(s => s.trim());
            if (property && value) {
              currentStyles[property] = value;
            }
          }
        }
      }
      
      // 合并继承样式和当前样式（当前样式优先级更高）
      const finalStyles = { ...inheritedStyles, ...currentStyles };
      
      // 构建最终样式字符串
      const styleArray: string[] = [];
      for (const [property, value] of Object.entries(finalStyles)) {
        if (value) {
          // 处理特殊的属性名映射
          const cssProperty = property === 'fontSize' ? 'font-size' : property;
          styleArray.push(`${cssProperty}: ${value}`);
        }
      }
      
      // 设置span的样式
      if (styleArray.length > 0) {
        span.setAttribute('style', styleArray.join('; '));
      }
      
      // 移动所有子节点到span中
      while (fontTag.firstChild) {
        span.appendChild(fontTag.firstChild);
      }
      
      // 替换font标签为span标签
      fontTag.parentNode?.replaceChild(span, fontTag);
    }
    
    // 处理其他子元素中可能包含的font标签
    for (const child of Array.from(element.children)) {
      if (child.tagName.toLowerCase() !== 'font') {
        processFontTags(child);
      }
    }
  }

  // 处理所有font标签
  processFontTags(tempDiv);
  
  return tempDiv.innerHTML;
}

/**
 * Font标签转换插件
 * 在粘贴时自动将遗留的font标签转换为现代的span标签带CSS样式
 */
export default function FontTagTransformPlugin(): null {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    return editor.registerCommand(
      PASTE_COMMAND,
      (event: ClipboardEvent) => {
        const clipboardData = event.clipboardData;
        if (!clipboardData) {
          return false;
        }

        const htmlData = clipboardData.getData('text/html');
        
        // 检查是否包含font标签
        if (htmlData && htmlData.includes('<font')) {
          // 阻止默认粘贴行为
          event.preventDefault();
          
          // 转换font标签
          const transformedHTML = transformFontTags(htmlData);
          
          // 创建新的粘贴事件
          const newDataTransfer = new DataTransfer();
          newDataTransfer.setData('text/html', transformedHTML);
          
          // 保留纯文本数据
          const textData = clipboardData.getData('text/plain');
          if (textData) {
            newDataTransfer.setData('text/plain', textData);
          }
          
          // 创建新的粘贴事件
          const newPasteEvent = new ClipboardEvent('paste', {
            bubbles: true,
            cancelable: true,
            clipboardData: newDataTransfer,
          });
          
          // 延迟分发新的粘贴事件，让当前事件完成处理
          setTimeout(() => {
            const editorElement = editor.getRootElement();
            if (editorElement) {
              editorElement.dispatchEvent(newPasteEvent);
            }
          }, 0);
          
          return true; // 表示我们处理了这个事件
        }
        
        return false; // 让其他处理器继续处理
      },
      COMMAND_PRIORITY_LOW, // 使用较低优先级，让其他插件先处理
    );
  }, [editor]);

  return null;
}